package com.omp.common.util;

import org.apache.commons.lang.StringUtils;

/**
 * 获得唯一且有序的主键
 */
public class UID {
	private static long lastTime = System.currentTimeMillis();
	private static short lastCount = -32768;
	private static Object mutex = new Object();
	private static long ONE_SECOND = 1000L;

	public UID() {
		
	}

	public static String getUID() {
		long l = 0L;
		short word0 = 0;
		int i = 0;
		synchronized (mutex) {
			if (lastCount == 32767) {
				for (boolean flag = false; !flag;) {
					l = System.currentTimeMillis();
					if (l < lastTime + ONE_SECOND) {
						try {
							Thread.currentThread();
							Thread.sleep(ONE_SECOND);
						} catch (InterruptedException interruptedexception) {
						}
					} else {
						lastTime = l;
						lastCount = -32768;
						flag = true;
					}
				}
			} else {
				l = lastTime;
			}
			word0 = lastCount++;
			i = getHostUniqueNum();
		}
		String s = fillUp(Integer.toString(i, 16), 6) + fillUp(Long.toString(l, 16), 11) + fillUp(Integer.toString(word0, 16), 5);
		if (s.length() > 22) {
			s = s.substring(s.length() - 22);
		}
		return s;
	}

	private static int getHostUniqueNum() {
		return (new Object()).hashCode();
	}

	public static void main(String[] args) {
		for (int i = 0;i < 100000;i++) {
			System.out.println(getUID());
		}
	}
	
	/**
	 * 按长度补齐字符串（在字符串前填充“0”），如果超出了长度，会从第一个字符截取到补齐长度。
	 * @date 2012-10-24
	 * @param str 要补齐要字符串
	 * @param length 补齐长度
	 * @return String 补齐后的字符串
	 */
	private static String fillUp(String str, int length) {
		//为空或全是空格
		if (StringUtils.isBlank(str) || str.trim().length() == 0) {
			return "";
		}
		//符合指定长度
		if (str.length() == length) {
			return str;
		}
		StringBuffer sb = new StringBuffer();
		if (str.length() < length) { //小于指定长度
			//补0
			for (int j = str.length();j < length;j++) {
				sb.append(0);
			}
			sb.append(str);
		} else if (str.length() > length) { //大于指定长度
			//截取
			return str.substring(0, length);
		}
		return sb.toString();
	}
}
